home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 7
/
FM Towns Free Software Collection 7.iso
/
ms_dos
/
the
/
the.asm
next >
Wrap
Assembly Source File
|
1993-11-30
|
31KB
|
1,821 lines
;**************************************************
;
; “THe”リアル版エディタ
;
; By 五味仁
;
;**************************************************
;**********************************************************************
;v0.01 テストバージョン 92/04/25
;v0.10 最低機能バージョン 92/07/23~
;v0.20 超暫定バージョン ~92/09/20
;v0.53 暫定バージョン 92/09/24
;v0.55 暫定バグフィックス 93/06/26
;v0.55a シフト+右をサポート 93/07/14
;**********************************************************************
IDEAL
DOSSEG
P8086
JUMPS
CR EQU 0DH,0AH
NULL EQU 00H
FULL EQU 48*1024 ;最大編集サイズ
SEGMENT CODE WORD "CODE"
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
ORG 100H ;“THe.com”
;******************************************************************************
; スタートアップ処理
;******************************************************************************
ENTRY:
CLD
MOV AX,CS
MOV DS,AX ;DSをCSに合わせる
MOV ES,AX
;******************************
; コマンドライン
;******************************
GETCMD:
MOV SI,81H ;移し元ポインタ(双方とも、)
XOR BP,BP ;ポインタのポインタ
JMP GETCMD4
GETCMDP:
MOV [WORD CMDPOINTER+BP],SI
INC BP
INC BP ;ポインタ設定
GETCMD2:
CMP [BYTE SI],0DH
JE GETCMD5 ;最後の処理へ
CMP [BYTE SI],20H
JE GETCMD3 ;飛ばし処理へ
INC SI
JMP GETCMD2
GETCMD3:
MOV [BYTE SI],00H
INC SI ;まずヌル入れ
GETCMD4:
CMP [BYTE SI],0DH
JE GETCMD5 ;最後の処理へ
CMP [BYTE SI],20H
JNE GETCMDP ;スペースじゃなかったら帰る
INC SI
JMP GETCMD4 ;スペースだったら移動してまた調べる
GETCMD5:
MOV [BYTE SI],00H ;埋め込んで終わり
MOV [WORD CMDCOUNTER],BP
XOR BX,BX
MOV DX,0FFFFH
READCMD:
CMP BP,BX
JE READEND
MOV DI,[WORD CMDPOINTER+BX]
CMP [BYTE DI],"-"
JE OP_READ
CMP [BYTE DI],"/"
JE OP_READ
MOV DX,DI
COMEREAD:
INC BX
INC BX
JMP READCMD
OP_READ:
JMP COMEREAD ;現行、オプション無し
READEND:
CMP DX,0FFFFH
JNE READEND2 ;ファイル名指定なら、ロードへ
MOV [BYTE FNAME],NULL
JMP MAIN
READEND2:
MOV SI,DX
MOV DI,OFFSET FNAME
CALL STRCPY
CALL LOAD
;******************************************************************************
; 初期設定と画面を描く
;******************************************************************************
MAIN:
MOV AX,0501H
INT 90H ;クリック音無し
MOV AH,00H
INT 91H ;コンソールBIOS初期化(消去)
MOV AH,09H
MOV AL,11110000B
INT 91H ;カーソル形状設定(ボックス)
MOV AH,1BH
MOV AL,01000010B
INT 91H ;表示属性の決定
MOV AX,CS
MOV [WORD SYSLINE+02H],AX
MOV [WORD SYSLINE+06H],AX
MOV AX,1F01H
MOV CX,70
MOV DL,01H
MOV DI,OFFSET SYSLINE
INT 91H ;システム行書き込み。
MOV AH,11H
MOV DI,OFFSET SYSATTLIB+4
INT 91H ;リバース
MOV AH,1EH
MOV CX,160
MOV DI,OFFSET UPPART
INT 91H ;上の文字を書く
MOV AH,11H
MOV DI,OFFSET SYSATTLIB+0
INT 91H ;リバース解除
MOV BX,OFFSET EBUF
MOV [WORD CURP],BX
MOV [WORD NOWL],BX ;ポインタセット
CMP [BYTE FNAME],NULL
JE READ ;ファイル名。無指定なら、読み込みへ
CALL NOWLINE
CALL SCREEN ;画面表示
MOV CX,01
CALL NS_PUT ;現在の状態を書く
CALL W_FNAME ;ファイル名を書く
;******************************************************************************
; キー読み取り(事実上メイン)
;******************************************************************************
OAKLOOP1:
MOV [WORD CHAN],0
CALL PUTCUR
MOV AX,0900H
INT 90H ;一文字入力。フリーウェアで(DOSで)、
;漢字の処理も、ここでやってくれる。
CMP DL,20H
JB OAKLOOP1B ;普通のキー入力ならそこへ
NOR_KEY:
;********************************
; 普通のキー入力
;********************************
CMP [WORD LEN],FULL
JA OAKLOOP1 ;サイズオーバーなら無効
INC [WORD CHAN] ;一括の為のカウンター
MOV SI,OFFSET EBUF
ADD SI,[WORD LEN]
MOV DI,SI
MOV CX,SI
SUB CX,[WORD CURP] ;差を出す
DEC SI
STD
REP MOVSB
CLD
MOV BX,[WORD CURP]
MOV [BYTE BX],DL
INC [WORD LEN]
INC [WORD CURP]
MOV [BYTE PF],1
MOV AH,07H
INT 90H
CMP DH,0FFH
JNE NOR_KEY2 ;入力文字無しは?
NOR_KEY1A:
CALL NOWLINE
MOV AX,[WORD CHAN]
SUB [WORD CURP],AX
NOR_LOOP:
DEC [WORD CHAN]
CALL CHARIGHT
CMP [WORD CHAN],0
JNE NOR_LOOP
MOV CX,[WORD CURL]
CALL NS_PUT
CALL SCREEN
JMP OAKLOOP1
NOR_KEY2:
CMP DL,20H
JB NOR_KEY1A
MOV AX,0900H
INT 90H
JMP NOR_KEY
OAKLOOP1B:
CMP DL,9
JE NOR_KEY ;タブ入力
CMP DL,1EH
JNE OAKLOOP2
;********************************
; 上移動
;********************************
MOV AX,0600H
INT 90H ;バッファのクリア
MOV DI,01
AND BL,00000100B
CMP BL,00000100B
JNE NORMALUP
MOV DI,10
NORMALUP:
CALL CURUP
CALL NS_PUT ;現在の状態を書く
CALL SCREEN ;画面表示
JMP OAKLOOP1
OAKLOOP2:
CMP DL,1FH
JNE OAKLOOP3
;********************************
; 下移動
;********************************
MOV AX,0600H
INT 90H ;バッファのクリア
MOV DI,01
AND BL,00000100B
CMP BL,00000100B
JNE NORMALDOWN
MOV DI,10
NORMALDOWN:
CALL CURDOWN
CALL NS_PUT ;現在の状態を書く
CALL SCREEN ;画面表示
JMP OAKLOOP1
OAKLOOP3:
CMP DL,1CH
JNE OAKLOOP4
;********************************
; 右移動
;********************************
MOV AX,0600H
INT 90H ;バッファのクリア
AND BL,00000100B
CMP BL,00000100B
JNE NORMALRIGHT
SHIFTRIGHT:
MOV BX,[WORD CURL]
CMP BX,[WORD LLINE]
JA SR_SKIP
SHL BX,1
MOV BX,[WORD ELINE+BX]
MOV [WORD CURP],BX
INC [WORD CURL]
MOV [BYTE CURX],1
SR_SKIP:
CALL CURLEFT
CALL NS_PUT ;現在の状態を書く
CALL SCREEN ;画面表示
JMP OAKLOOP1
NORMALRIGHT:
CALL CURRIGHT
CALL NS_PUT ;現在の状態を書く
CALL SCREEN ;画面表示
JMP OAKLOOP1
OAKLOOP4:
CMP DL,1DH
JNE OAKLOOP5
;********************************
; 左移動
;********************************
MOV AX,0600H
INT 90H ;バッファのクリア
TEST BL,01100100B
JE NORMALLEFT
SHIFTLEFT:
MOV BX,[WORD CURL]
MOV CX,BX
DEC BX
SHL BX,1
MOV BX,[WORD ELINE+BX]
MOV [WORD CURP],BX
CALL NS_PUT ;現在の状態を書く
CALL SCREEN ;画面表示
JMP OAKLOOP1
NORMALLEFT:
CALL CURLEFT
CALL NS_PUT ;現在の状態を書く
CALL SCREEN ;画面表示
JMP OAKLOOP1
OAKLOOP5:
CMP DL,0DH
JNE OAKLOOP6
;********************************
; リターン
;********************************
CMP [WORD LEN],FULL
JA OAKLOOP1 ;サイズオーバーなら無効
MOV AX,0600H
INT 90H ;バッファのクリア
MOV SI,OFFSET EBUF
ADD SI,[WORD LEN]
MOV DI,SI
MOV CX,SI
SUB CX,[WORD CURP] ;差を出す
INC DI
DEC SI ;BUG FIXED(93/06/26 )
STD
REP MOVSB
CLD
MOV BX,[WORD CURP]
MOV [BYTE BX] ,0DH
MOV [BYTE BX+1],0AH
INC [WORD LEN]
INC [WORD LEN]
MOV [BYTE PF],1
CALL NOWLINE
CALL CHARIGHT
MOV [BYTE PF],1
CALL NS_PUT
CALL SCREEN
JMP OAKLOOP1
OAKLOOP6:
CMP DL,08H
JNE OAKLOOP7
;********************************
; バックスペース
;********************************
AND BL,00000100B
CMP BL,00000100B
JNE NORMALBS
NORMALBS:
CALL CURLEFT
MOV [BYTE PF],0 ;変更なし、として、下のルーチンの時間をかせぐ
CALL SCREEN ;その場所が全角か半角かを求めるのに使っている
JMP DEKEY ;実は、バックスペースは、左+削除だ!
OAKLOOP7:
OAKPFKEY1:
MOV AX,0600H
INT 90H ;バッファのクリア
;********************************
; 終了
;********************************
CMP BH,66H ;PF10(終了)
JE FIN
;********************************
; 読み込み
;********************************
CMP BH,5EH ;PF 2(読込)
JNE WRITE
READ:
CALL INPUT_NAME
CALL W_FNAME ;ファイル名を書く
JMP FOR_RENAME
;********************************
; 更新
;********************************
WRITE:
CMP BH,61H ;PF 5(更新)
JNE SAVEND
CALL UPDATE
JMP OAKLOOP1
;********************************
; 保存
;********************************
SAVEND:
CMP BH,5DH ;PF 1(保存)
JNE RENAME
CALL UPDATE ;保存へ
CMP AX,0
JE FIN ;エラーだったら終了せず
JMP OAKLOOP1
;********************************
; 改名
;********************************
RENAME:
CMP BH,5FH ;PF 3(改名)
JNE REEDIT
CALL INPUT_NAME
CALL W_FNAME ;ファイル名を書く
MOV [BYTE PF],1
CALL SCREEN ;画面表示
JMP OAKLOOP1
;********************************
; 再編集
;********************************
REEDIT:
CMP BH,60H ;PF 4(再編集)
JNE DELE
FOR_RENAME:
MOV DX,OFFSET FNAME
CALL LOAD
CALL NOWLINE
CALL NS_PUT ;現在の状態を書く
CALL SCREEN ;画面表示
JMP OAKLOOP1
;********************************
; 削除
;********************************
DELE:
CMP BH,4BH
JNE OAKPFKEY2 ;削除
DEKEY:
MOV DI,[WORD CURP]
MOV AL,[BYTE DI]
MOV AH,[BYTE DI+1] ;リターンコード処理
MOV BP,OFFSET EBUF
ADD BP,[WORD LEN] ;しょっちゅう出てくるから、作ろうか?
CMP DI,BP
JE OAKLOOP1
MOV SI,DI
INC SI
CMP AL,0DH
JNE DEKEY2
CMP AH,0AH
JNE DEKEY2
INC SI ;リターンコード一括削除
DEC [WORD LEN] ;更新
DEKEY2:
MOV AX,[WORD ZHF]
ADD SI,AX ;全角か?
SUB [WORD LEN],AX
MOV CX,BP
SUB CX,SI ;差を出す
REP MOVSB ;CLD前提
DEC [WORD LEN] ;更新
DEKEY3:
CALL NOWLINE
MOV [BYTE PF],1
CALL NS_PUT
CALL SCREEN
JMP OAKLOOP1
OAKPFKEY2:
JMP OAKLOOP1 ;判読不能
;****************************************************************************
; 壮大な終了!!
;
; また起動するのだ。
;****************************************************************************
FIN:
MOV AX,0600H
INT 90H ;バッファのクリア
XOR AH,AH
INT 91H ;コンソールBIOS初期化
MOV AH,4CH
INT 21H
;****************************************************************************
; 更新ルーチン
;
;
;****************************************************************************
PROC UPDATE
MOV AH,3CH
MOV DX,OFFSET FNAME
MOV CX,0000000000000000B
INT 21H
JC UPD_ERR_RET
MOV BX,AX
MOV AH,40H
MOV DX,OFFSET EBUF
MOV CX,[WORD LEN]
INT 21H
JC UPD_ERR_RET
MOV AX,0
RET
UPD_ERR_RET:
MOV AX,1 ;エラー処理
RET
ENDP
;****************************************************************************
; 名前入力ルーチン
;
;
;****************************************************************************
PROC INPUT_NAME
MOV AH,11H
MOV DI,OFFSET SYSATTLIB+4
INT 91H ;リバース
MOV AH,0DH
MOV DH,12
MOV DL,01
INT 91H ;カーソル移動
MOV AH,1EH
MOV CX,80
MOV DI,OFFSET SPA80
INT 91H
MOV AH,0DH
MOV DH,14
MOV DL,01
INT 91H ;カーソル移動
MOV AH,1EH
MOV CX,80
MOV DI,OFFSET SPA80
INT 91H
MOV AH,11H
MOV DI,OFFSET SYSATTLIB+0
INT 91H ;リバース解除
MOV AH,0DH
MOV DH,13
MOV DL,01
INT 91H ;カーソル移動
MOV AH,1EH
MOV CX,80
MOV DI,OFFSET SPA80
INT 91H
MOV AH,0DH
MOV DH,13
MOV DL,02
INT 91H ;カーソル移動
MOV AH,1BH
MOV AL,11000010B
INT 91H ;表示属性の決定
MOV AH,0AH
MOV DX,OFFSET TMP_NAME
INT 21H
MOV AH,1BH
MOV AL,01000010B
INT 91H ;表示属性の決定
MOV SI,OFFSET TMP_NAME+2
MOV DI,OFFSET FNAME
@@_1:
LODSB
STOSB ;CLD前提
CMP AL,0DH
JNE @@_1
MOV [BYTE DI-1],NULL
RET
ENDP
;******************************************************************************
; ファイルをロード
;IN DX
;OUT AX(00H=正常終了,01H=失敗)
;BREAK AX,BX,CX,SI
;******************************************************************************
PROC LOAD
MOV AX,03D00H
INT 21H ;オープン
JC ERET ;エラーリターン
MOV BX,AX ;ファイルハンドルをBXに移す
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H ;ファイルの最後を求める
CMP DX,00H
JNE ERET ;サイズが16ビットを越えていたらエラー
CMP AX,FULL
JA ERET ;サイズがFULLバイトを越えていたらエラー
MOV [WORD LEN],AX
MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H ;ファイルの最初に戻す
HNEXT:
MOV CX,[WORD LEN] ;一度に読む
XOR SI,SI ;ポインタ初期化
MOV DX,OFFSET EBUF ;先頭に
HREAD:
MOV AH,03FH
INT 21H
JC ERET ;簡易エラー表示
CLOSE:
MOV AH,3EH
INT 21H ;クローズ
JC ERET ;クローズ出来ない
MOV BX,OFFSET EBUF
MOV [WORD CURP],BX
MOV [WORD NOWL],BX ;ポインタセット
MOV [BYTE PF],1 ;改変されたというフラグ
MOV AX,00H ;ロード完了
RET
ERET:
MOV BX,OFFSET EBUF
MOV [WORD CURP],BX
MOV [WORD NOWL],BX ;ポインタセット
MOV [BYTE PF],1 ;改変されたというフラグ
MOV [WORD LEN],0
MOV AX,01H
RET
ENDP LOAD
;******************************************************************************
; スクリーン表示
;IN NOWL
;OUT 表示
;BREAK AX,CX,DX,BP,SI,DI,SCRBUF
;******************************************************************************
PROC SCREEN
PUSH BX ;全角フラグ
XOR BL,BL ;0は半角(半額では無い)
MOV SI,[WORD NOWL] ;先頭行ポインタ
MOV DI,OFFSET SCRBUF ;表示バッファ
XOR DX,DX ;行、桁ポインタ
MOV BP,[WORD LEN] ;編集テキスト長
ADD BP,OFFSET EBUF ;EOFポイント
SCRLOOP1:
MOV AL,[BYTE SI]
MOV [BYTE DI],AL
CMP BL,1
JE HAN ;前の文字が全角先頭なら次は全角後尾
CMP AL,0DFH
JA ZEN
CMP AL,80H
JB EOZ
CMP AL,09FH
JA EOZ ;前が半角なら、次が全角先頭か判断
ZEN:
MOV BL,1
JMP EOZ ;全角先頭と判断
HAN:
XOR BL,BL ;全角先頭のフラグを下げる
EOZ:
CMP [WORD CURP],SI
JNE SCRLOOP1B
PUSH DX
INC DL
INC DH
INC DH
INC DH
MOV [BYTE CURX],DL
MOV [BYTE CURY],DH
POP DX
CMP BL,0
JE CZ2
CZ1:
MOV AH,09H
MOV AL,11110000B
INT 91H ;カーソル形状設定(全角)
MOV [WORD ZHF],1 ;保存フラグ
JMP SCRLOOP1B
CZ2:
MOV AH,09H
MOV AL,01110000B
INT 91H ;カーソル形状設定(半角)
MOV [WORD ZHF],0 ;保存フラグ
;注:コンソールエミューターではカーソルの形が変えられなかった。
;注:本物のコンソールでも変えられなかった…。
SCRLOOP1B:
CMP BP,SI
JE SCRPUT ;EOFで表示へ
CMP DH,21
JE SCRPUT ;行限界で表示へ
CMP [BYTE SI],0DH
JNE SCRLOOP3
DEC BP
CMP BP,SI
INC BP
JE SCRLOOP3
CMP [BYTE SI+1],0AH
JNE SCRLOOP3
INC SI
INC SI ;ポインタの移動
MOV AL,20H ;半角スペース
SCRLOOP2:
CMP DL,80
JE SCRLOOP2E
STOSB
INC DL
JMP SCRLOOP2
SCRLOOP2E:
XOR DL,DL
INC DH
XOR BL,BL
JMP SCRLOOP1
SCRLOOP3:
CMP [BYTE SI],09H
JNE SCRLOOP4
XOR BL,BL
INC SI
MOV AL,DL
SHR AL,1
SHR AL,1
SHR AL,1
INC AL
SHL AL,1
SHL AL,1
SHL AL,1
CMP AL,80
JB SCRLOOP3B
MOV AL,80
SCRLOOP3B:
MOV [BYTE DI],20H
INC DI
INC DL
CMP AL,DL
JNE SCRLOOP3B
JMP SCRLOOP4B ;BUG FIXED 92/07/30 22:05:49
SCRLOOP4:
INC SI
INC DI
INC DL
SCRLOOP4B:
CMP DL,80
JNE SCRLOOP1 ;80文字目か判断
CMP BL,1
JNE EOZ2 ;全角先頭か判断
DEC SI
DEC DI ;戻して
MOV [BYTE DI],1CH ;『→』に書換えて
XOR DL,DL ;桁ポインタ操作
INC DH ;行を増やす
INC DI
MOV AL,[BYTE SI]
MOV [BYTE DI],AL
JMP EOZ
EOZ2:
XOR DL,DL
INC DH
JMP SCRLOOP1
SCRPUT:
CMP DI,OFFSET SCRBUF+80*21
JE SCRPUT2
MOV [BYTE DI],20H
INC DI
JMP SHORT SCRPUT
SCRPUT2:
CMP [BYTE PF],0
JE SCRRET
mov ah,0bh
mov al,1
int 91h ;カーソル非表示
MOV AH,0DH
MOV DX,0301H
INT 91H
MOV AH,1EH
MOV DI,OFFSET SCRBUF
MOV CX,80*21
INT 91H
mov ah,0bh
mov al,0
int 91h ;カーソル表示
MOV [BYTE PF],0
SCRRET:
POP BX
RET
ENDP
;******************************************************************************
; カーソルを描く
;IN CURX,CURY
;OUT 表示
;BREAK AX,DX
;******************************************************************************
PROC PUTCUR
MOV DL,[BYTE CURX]
MOV DH,[BYTE CURY]
MOV AH,0DH
INT 91H
RET
ENDP
;******************************************************************************
; 文字を打った後のカーソルを右に移動
;IN CURX,CURY
;OUT CURX,CURY,表示,CURP,SI
;BREAK BX,CX,DX
;******************************************************************************
PROC CHARIGHT
MOV CX,[WORD CURL]
MOV SI,[WORD CURP]
MOV DL,[BYTE CURX]
MOV DH,[BYTE CURY]
MOV BP,[WORD LEN] ;編集テキスト長
ADD BP,OFFSET EBUF ;EOFポイント
CHALOOP1:
CMP [BYTE SI],0DH
JNE CHALOOP1B
DEC BP
CMP SI,BP
INC BP
JE CHALOOP1B
CMP [BYTE SI+1],0AH
JNE CHALOOP1B
INC SI
CHALOOP1B:
INC SI
MOV BP,CX
SHL BP,1
MOV BX,[WORD ELINE+BP] ;次の行の先頭ポインタを求める
CMP SI,BX ;同じなら、次の行に行っている
JNE CHARET
CMP DH,22
JNE CHALOOP2
CALL DOWN
INC [BYTE PF] ;動いた
INC CX
JMP CHARET
CHALOOP2:
INC DH ;カーソル下
INC CX
CHARET:
MOV [WORD CURP],SI
MOV [WORD CURL],CX
RET
ENDP
;******************************************************************************
; カーソルを右に移動
;IN CURX,CURY
;OUT CURX,CURY,表示,CURP,SI
;BREAK BX,CX,DX
;******************************************************************************
PROC CURRIGHT
MOV CX,[WORD CURL]
MOV SI,[WORD CURP]
MOV DL,[BYTE CURX]
MOV DH,[BYTE CURY]
MOV BP,[WORD LEN] ;編集テキスト長
ADD BP,OFFSET EBUF ;EOFポイント
CRILOOP1:
CMP SI,BP
JE CRIRET
CMP [WORD ZHF],1
JE MMRIGHT
CMP [BYTE SI],0DH
JNE CRILOOP1B
DEC BP
CMP SI,BP
INC BP
JE CRILOOP1B
CMP [BYTE SI+1],0AH
JNE CRILOOP1B
MMRIGHT:
INC SI
CRILOOP1B:
INC SI
MOV BP,CX
SHL BP,1
MOV BX,[WORD ELINE+BP] ;次の行の先頭ポインタを求める
CMP SI,BX ;同じなら、次の行に行っている
JNE CRIRET
CMP DH,22
JNE CRILOOP2
CALL DOWN
INC [BYTE PF] ;動いた
INC CX
JMP CRIRET
CRILOOP2:
INC DH ;カーソル下
INC CX
CRIRET:
MOV [WORD CURP],SI
MOV [WORD CURL],CX
RET
ENDP
;******************************************************************************
; カーソルを左に移動
;IN CURX,CURY
;OUT CURX,CURY,表示,CURP,SI
;BREAK BX,CX,DX
;******************************************************************************
PROC CURLEFT
MOV CX,[WORD CURL]
MOV SI,[WORD CURP]
MOV DL,[BYTE CURX]
MOV DH,[BYTE CURY]
CLELOOP1:
CMP SI,OFFSET EBUF
JE CLERET ;左不可
MOV BP,CX
DEC BP
SHL BP,1 ;行からポインタになおす
CMP SI,[WORD ELINE+BP]
JNE CLELOOP2
MOV DL,79 ;理想桁指定
MOV DI,1
MOV SI,OFFSET EBUF
MOV [BYTE PF],0
JMP CUPLOOP1
CLELOOP2:
DEC DL
JMP CUPRET ;超無謀!
CLERET:
RET ;おまけ
ENDP
;******************************************************************************
; カーソルを上に移動
;IN CURX,CURY,DI
;OUT CURX,CURY,表示,CURP,SI
;BREAK BX,CX,DX
;******************************************************************************
PROC CURUP
MOV CX,[WORD CURL]
MOV [BYTE PF],0
MOV DL,[BYTE CURX]
MOV DH,[BYTE CURY]
MOV SI,OFFSET EBUF
CUPLOOP1:
CMP CX,01
JE CUPRET ;移動不能
CMP DH,04
JNE CUPLOOP2
CMP CX,02
JE CUPLOOP2 ;移動不能
CALL UP
INC [BYTE PF] ;動いた
DEC CX
DEC DI
CMP DI,00
JNE CUPLOOP1
JMP CUPRET
CUPLOOP2:
DEC DH ;カーソル上
DEC CX
DEC DI ;回数ポインタを減らす
CMP DI,00
JNE CUPLOOP1 ;無くなるまで繰り返す
CUPRET:
MOV BP,CX
DEC BP
SHL BP,1 ;行からポインタになおす
MOV BX,[WORD ELINE+BP] ;BXに現在行頭のポインタを入れる
MOV [WORD CURL],CX ;行をしまう
PUSH CX ;何が入っていたか忘れたけど保存する
XOR DH,DH ;DXを、目標桁とする
;(DLをDXとして使う)
MOV CX,OFFSET EBUF
ADD CX,[WORD LEN]
MOV [WORD EBLEN],CX ;仮のEOFポインタ
XOR CX,CX ;CXを、現在桁とする
CUPRET2:
CUPRET2B:
MOV AX,BX ;CXの過去をAXとする
CMP BX,[WORD EBLEN]
JE CUPRET3 ;EOFなら
CMP [BYTE BX],0DH
JNE CUPRET2C
CMP [BYTE BX+1],0AH
JE CUPRET3 ;リターンチェック
CUPRET2C:
CMP [BYTE BX],09H
JNE CUPRET2E ;タブで無いなら飛ばす
SHR CL,1
SHR CL,1
SHR CL,1
INC CL
SHL CL,1
SHL CL,1
SHL CL,1
CMP CL,80
JNB CUPRET3
CUPRET2D:
INC BX ;ポインタ移動
JMP SAITEUP
CUPRET2E:
CMP [BYTE BX],0DFH
JA ZENUP
CMP [BYTE BX],80H
JB EOZUP
CMP [BYTE BX],09FH
JA EOZUP ;前が半角なら、次が全角先頭か判断
ZENUP:
INC BX
INC CL
EOZUP:
INC BX
INC CL ;ポインタと桁を両方移動させる
SAITEUP:
CMP DX,CX
JA CUPRET2 ;越えていたら処理終了。越える前の値は、
;AXに入っているので楽勝。
CUPRET3:
MOV [WORD CURP],AX ;上を見ること
POP CX ;復元
RET
ENDP
;******************************************************************************
; カーソルを下に移動
;IN CURX,CURY,DI
;OUT CURX,CURY,表示,CURP,SI
;BREAK BX,CX,DX
;******************************************************************************
PROC CURDOWN
MOV CX,[WORD CURL]
MOV [BYTE PF],0
MOV DL,[BYTE CURX]
MOV DH,[BYTE CURY]
MOV SI,OFFSET EBUF
CDNLOOP1:
CMP CX,[WORD LLINE]
JE CDNRET ;移動不能
CMP DH,22
JNE CDNLOOP2
CALL DOWN
INC [BYTE PF] ;動いた
INC CX
DEC DI
CMP DI,00
JNE CDNLOOP1
JMP CDNRET
CDNLOOP2:
INC DH ;カーソル下
INC CX
DEC DI
CMP DI,00
JNE CDNLOOP1
CDNRET:
JMP CUPRET ;カーソル上移動のルーチンを借りている
RET
ENDP
;******************************************************************************
; 表示画面上移動
;IN NOWL
;OUT NOWL
;BREAK BP,BX
;******************************************************************************
PROC UP
MOV BP,CX
; MOV BL,DH ;DHは常に4
; XOR BH,BH
; DEC BL
; DEC BL
; DEC BL
SUB BP,1 ;BX → 1 汎用ルーチンとして残しておく。
DEC BP
DEC BP
SHL BP,1
MOV BX,[WORD ELINE+BP]
MOV [WORD NOWL],BX
UPRET:
RET
ENDP
;******************************************************************************
; 表示画面下移動
;IN NOWL
;OUT NOWL
;BREAK BP,BX
;******************************************************************************
PROC DOWN
MOV BP,CX
; MOV BL,DH ;DHは常に22
; XOR BH,BH
; DEC BL
; DEC BL
; DEC BL
SUB BP,19 ;BX → 19 汎用ルーチンとして残しておく
SHL BP,1
MOV BX,[WORD ELINE+BP]
MOV [WORD NOWL],BX
DOWNRET:
RET
ENDP
;******************************************************************************
; 現在のステータスを書く
;IN CURP,LEN,LLINE,CX
;OUT 表示
;BREAK AH,DX,DI
;******************************************************************************
PROC NS_PUT
mov ah,0bh
mov al,1
int 91h ;カーソル非表示
MOV AH,11H
MOV DI,OFFSET SYSATTLIB+4
INT 91H ;リバース
MOV AH,0DH
MOV DH,02
MOV DL,69
INT 91H ;カーソル移動
CALL PUT16BIT ;現在行を書く
MOV AH,0DH
MOV DH,01
MOV DL,69
INT 91H ;カーソル移動
MOV CX,[WORD CURP]
SUB CX,OFFSET EBUF
CALL PUT16BIT ;サイズを書く
MOV AH,0DH
MOV DH,01
MOV DL,75
INT 91H ;カーソル移動
MOV CX,[WORD LEN]
CALL PUT16BIT ;サイズを書く
MOV AH,0DH
MOV DH,02
MOV DL,75
INT 91H ;カーソル移動
MOV CX,[WORD LLINE]
CALL PUT16BIT ;最終行を書く
MOV AH,11H
MOV DI,OFFSET SYSATTLIB+0
INT 91H ;リバース解除
mov ah,0bh
mov al,0
int 91h ;カーソル表示
RET
ENDP
;******************************************************************************
; ファイルネームを書く
;
;
;******************************************************************************
PROC W_FNAME
WF_LOOP:
MOV SI,OFFSET FNAME
MOV DI,SI
DEC DI
WF_LOOP1:
CMP [BYTE SI],"\"
JE WF_LOOP3
CMP [BYTE SI],NULL
JE WF_LOOP4
WF_LOOP2:
INC SI
JMP WF_LOOP1
WF_LOOP3:
MOV DI,SI
JMP WF_LOOP2
WF_LOOP4:
INC DI
SUB SI,DI
MOV CX,SI
PUSH DI
PUSH CX
FN_PUT:
mov ah,0bh
mov al,1
int 91h ;カーソル非表示
MOV AH,11H
MOV DI,OFFSET SYSATTLIB+4
INT 91H ;リバース
MOV AH,0DH
MOV DH,01
MOV DL,01
INT 91H ;カーソル移動
MOV AH,1EH
MOV CX,160
MOV DI,OFFSET UPPART
INT 91H ;上の文字を書く
CALL NS_PUT
MOV AH,0DH
MOV DH,02
MOV DL,17
INT 91H ;カーソル移動
MOV AH,11H
MOV DI,OFFSET SYSATTLIB+4
INT 91H ;リバース
MOV AH,1EH
POP CX
POP DI
INT 91H ;出力
MOV AH,11H
MOV DI,OFFSET SYSATTLIB+0
INT 91H ;リバース解除
mov ah,0bh
mov al,0
int 91h ;カーソル表示
RET
ENDP
;******************************************************************************
; 現在行の割り出し(と同時に行ポインタバッファに入れる)
;IN 〔EBUF〕
;OUT CX,BP(ポインタ)
;BREAK SI,DL
;******************************************************************************
PROC NOWLINE
XOR DH,DH ;全角先頭フラグ
MOV BX,[WORD CURP]
MOV SI,OFFSET EBUF ;総ポインタ
XOR DL,DL ;桁ポインタ
MOV BP,02 ;行カウンタ
PUSH DI
MOV DI,[WORD LEN]
ADD DI,OFFSET EBUF
JMP NOLLOOP1
NOLCOME:
INC SI
INC DL
NOLLOOP1:
MOV AL,[BYTE SI]
CMP DH,1
JE HANK ;前の文字が全角先頭なら次は全角後尾
CMP AL,0DFH
JA ZENK
CMP AL,80H
JB EOZK
CMP AL,09FH
JA EOZK ;前が半角なら、次が全角先頭か判断
ZENK:
MOV DH,1
JMP EOZK ;全角先頭と判断
HANK:
XOR DH,DH ;全角先頭のフラグを下げる
EOZK:
CMP SI,BX
JNE NOSAVE
MOV CX,BP
NOSAVE:
CMP SI,DI
JE NOLRET
CMP DL,80
JE NOLLOOP2
CMP DL,79
JNE NOSAVE2
CMP DH,1
JNE NOSAVE2
JMP NOLLOOP2
NOSAVE2:
CMP [BYTE SI],09H
JNE NOLLOOP1C
INC SI
MOV AL,DL
SHR AL,1
SHR AL,1
SHR AL,1
INC AL
SHL AL,1
SHL AL,1
SHL AL,1
NOLLOOP1B:
INC DL
CMP AL,DL
JNE NOLLOOP1B
JMP NOLLOOP1
NOLLOOP1C:
CMP [BYTE SI],0DH
JNE NOLCOME
DEC BX
CMP BX,SI
INC BX
JE NOLCOME
CMP [BYTE SI+1],0AH
JNE NOLCOME
INC SI
INC SI
NOLLOOP2:
MOV [WORD ELINE+BP],SI
INC BP
INC BP
XOR DL,DL
JMP NOLLOOP1
NOLRET:
MOV AX,BP
SHR AX,1
MOV [WORD LLINE],AX
MOV BP,CX
SHR CX,1
MOV [WORD CURL],CX
POP DI
RET
ENDP
;****************************************
; 16ビット自然数の書き出し
;IN CX
;BREAK AX、BX、CX、DX
;****************************************
PROC PUT16BIT
MOV AX,CX
XOR DX,DX
MOV BX,10000
DIV BX
MOV BL,AL
ADD AL,30H
MOV [BYTE GET16BUF+0],AL
MOV AL,BL
MOV BX,10000
MUL BX
SUB CX,AX
MOV AX,CX
MOV BX,1000
DIV BX
MOV BL,AL
ADD AL,30H
MOV [BYTE GET16BUF+1],AL
MOV AL,BL
MOV BX,1000
MUL BX
SUB CX,AX
MOV AX,CX
MOV BX,100
DIV BX
MOV BL,AL
ADD AL,30H
MOV [BYTE GET16BUF+2],AL
MOV AL,BL
MOV BX,100
MUL BX
SUB CX,AX
MOV AX,CX
MOV BX,10
DIV BX
MOV BL,AL
ADD AL,30H
MOV [BYTE GET16BUF+3],AL
MOV AL,BL
MOV BX,10
MUL BX
SUB CX,AX
MOV AX,CX
ADD AL,30H
MOV [BYTE GET16BUF+4],AL
MOV AH,1EH
MOV CX,5
MOV DI,OFFSET GET16BUF
INT 91H
RET
ENDP
;****************************************
; 俗に言う『strcpy』
;IN SI、DIに入れる。
;OUT BP(コピーした文字数)
;BREAK AL
;****************************************
PROC STRCPY
XOR BP,BP
STRCPY2:
MOV AL,[BYTE DS:SI+BP]
MOV [BYTE ES:DI+BP],AL
CMP AL,00H
JE STRCPY3
INC BP
JMP STRCPY2
STRCPY3:
RET
ENDP
;******************************************************************************
; 初期化データ部
;******************************************************************************
SYSLINE:
DW SYSCHAR
DW ?
DW SYSATTLIB
DW ?
SYSCHAR:
DB " ",4AH,5DH,42H,38H," " ;保存
DB " ",46H,49H,39H,7EH," " ;読込
DB " ",32H,7EH,4CH,3EH," " ;改名
DB " ",3AH,46H,4AH,54H,3DH,38H ;再編集
DB " ",39H,39H,3FH,37H," " ;更新
DB " "
DB " "
DB " "
DB " "
DB " ",3DH,2AH,4EH,3BH," " ;終了
SYSATTLIB:
DB 00H,00000000B,7,0
DB 00H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 00H,00001000B,7,0 ;保存
DB 00H,00000000B,7,0
DB 00H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 00H,00001000B,7,0 ;読込
DB 00H,00000000B,7,0
DB 00H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 00H,00001000B,7,0 ;改名
DB 00H,00000000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0 ;再編集
DB 00H,00000000B,7,0
DB 00H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 00H,00001000B,7,0 ;更新
DB 00H,00000000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00000000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00000000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00000000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00001000B,7,0
DB 00H,00000000B,7,0
DB 00H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 01H,00001000B,7,0
DB 03H,00001000B,7,0
DB 00H,00001000B,7,0 ;終了
UPPART:
DB " TH editor v0.55a "
DB " SIZE[00000/00000]"
DB " Edit Filename > "
DB " LINE[00000/00000]"
SPA80:
DB 80 DUP(20H)
TMP_NAME:
DB 80
DB ?
DB 80 DUP(?) ;名前入力用
;******************************************************************************
; 未初期化データ
;******************************************************************************
ELINE:
DW EBUF ;先頭
DW 1000H DUP(?) ;テキスト行ポインタ
FNAME:
DB 128 DUP(?) ;ファイルネーム
CMDPOINTER:
DW 80H DUP(?) ;コマンドライン・バッファ
CURX:
DB ? ;カーソル桁
CURY:
DB ? ;カーソル行
PF:
DB ? ;改変のフラグ(0=無変更)
LEN:
DW ? ;テキストの長さ
CMDCOUNTER:
DW ? ;コマンドライン・ポインタ
LLINE:
DW ? ;テキストの最終行
EBLEN:
DW ? ;EBUF+LEN(TMP)
CURP:
DW ? ;カーソルポインタ
CURL:
DW ? ;カーソル行
NOWL:
DW ? ;表示行の先頭ポインタ
CHAN:
DW ? ;文字一括数
ZHF:
DW ? ;全角半角フラグ(カーソル兼)
GET16BUF:
DB 5 DUP(?) ;GET16BITバッファ
SCRBUF:
DB 80*21+2 DUP(?) ;仮テキストVRAM
EBUF:
DB FULL DUP(?) ;テキストバッファ
ENDS CODE
END ENTRY